/*************************************************************************************************\
*																																																	*
* PROGRAM: tList      	      																																		*
* VERSION: 0																																											*
* PURPOSE: This program provides basic functionality for working with (pseudo)lists               *
* AUTHOR:	 Aswin Bouwmeester (aswin.bouwmeester@gmail.com)																				*
* DATE:		 okt 10, 2010	  																																				*
*																																																	*
\*************************************************************************************************/

#define _TLIST_
#pragma systemFile

#ifndef TLISTITEMTYPE
  #define TLISTITEMTYPE int
#endif

#ifndef TLISTLENGTH
  #define TLISTLENGTH 20
#endif

typedef struct{
  short length;
  short maxlength;
  TLISTITEMTYPE items[TLISTLENGTH];
} tList;

typedef enumWord
{
  stat_length      = 0,
  stat_min         = 1,
  stat_max         = 2,
  stat_mean        = 3,
  stat_median      = 4
} Tstatistics;


void addItem(tList &list,TLISTITEMTYPE val);
void dropitem(tList &list);
void SortList(tList &list);
float getListStat(tList &list, Tstatistics statistic);


// adds an item to the end of the list. If the list is full the first item will be dropped;
void addItem(tList &list,TLISTITEMTYPE val)
{
  if (list.maxlength==0)
    list.maxlength=TLISTLENGTH;
  if (list.length==list.maxlength)
  {
    // drop first item
    dropitem(list);
  }
  list.items[list.length]=val;
  list.length++;
}


// drops the first item from a list;
void dropitem(tList &list)
{
  TLISTITEMTYPE dummy;
  if (list.length>0)
  {
	  memcpy(list.items[0],list.items[1],sizeof(dummy)*(list.length-1));
	  list.length--;
  }
}


// sort a list;
void SortList(tList &list)
{
	TLISTITEMTYPE val;
	for(int j=list.length-1;j>0;j--)
	for(int i=1;i<=j;i++)
	{
	  if(list.items[i-1]>list.items[i])
	  {
	    val=list.items[i-1];
	    list.items[i-1]=list.items[i];
	    list.items[i]=val;
	  }
	}
}

// get a statistic from a list of values;
float getListStat(tList &list, Tstatistics statistic)
{
  float val;
  int i;
  tList temp;
  switch(statistic)
  {
    // return the number of items in the list;
    case stat_length:
      val=list.length;
    break;
    // return the lowest vaue in the list;
    case stat_min :
      for(i=0;i<list.length;i++)
      {
        if (i==0)
          val=list.items[0];
        if (list.items[i]<val)
          list.items[i]=val;
      }
    break;
    // return the highest value in the list;
    case stat_max:
      for(i=0;i<list.length;i++)
      {
        if (i==0)
          val=list.items[0];
        if (list.items[i]>val)
          list.items[i]=val;
      }
    break;
    //return the mean of the values in the list;
    case stat_mean:
      for(i=1;i<=list.length;i++)
        val=(((float)i-1)/(float)i)*val+(1/(float)i)*(float)list.items[i-1];
    break;
    // return the median value in the list;
    case stat_median:
      memcpy(temp,list,sizeof(list));
  		SortList(temp);
  		val=list.items[floor(list.length/2)];
		break;
    default:
  }
  return val;
}
